# encoding: utf-8
from app.extensions import log, db
from .models import User

from flask_restplus import Resource
from app.extensions.api import Namespace
from . import parameters, schemas
from app.modules.role.models import Role
from app.modules.common.utils import DbCommit, GetMD5, checkToken
from config import BaseConfig
from app.modules.common.schemas import BaseSchema
from app.modules.login.models import LoginToken

api = Namespace('user', description = "The interface for user operation")  # pylint: disable=invalid-name


@api.route('/')
class Users(Resource):
    @api.parameters(parameters.UserParameters())
    @api.response(schemas.UserSchema(many = False))
    @checkToken
    def get(self, args):
        """
        query user list or user info by user_id
        :param args:
        :return:
        """
        log.info("============== start query users ==============")
        _user_id = args['id']
        _role_name = args['role_name']
        _withRole = args['withRole']
        log.info("============== query users , user_id is %s,withRole is %s ==============" % (_user_id, _withRole))

        _query = db.session.query(User)

        if _user_id is not None:
            _query = _query.filter(User.id == _user_id)

        if _role_name is not None:
            _r = Role.query.filter_by(role_name = _role_name).first()
            if _r is None:
                _msg = '查询用户列表,角色名%s不存在' % _role_name
                log.error("============== %s ==============" % _msg)
                return {'success': False, 'msg': _msg}
            _list = []
            _list.append(str('%|'))
            _list.append(str(_r.role_id))
            _list.append(str('|%'))
            _user_role = ''.join(_list)
            _query = _query.filter(User.role.like('%s' % _user_role))

        _user_list = _query.all()
        if len(_user_list) == 0:
            _msg = "query users , user %s is not exist" % _user_id
            log.error("============== %s ==============" % _msg)
            return {'success': True, 'msg': '', 'data': _user_list}

        if _withRole:
            for _user in _user_list:
                _roles = str(_user.role).split("|")
                _role_list = []
                for _role_id in _roles:
                    if _role_id is not None and _role_id != '':
                        _role = Role.query.filter_by(role_id = _role_id).first()
                        if _role is not None:
                            _role_list.append(_role)
                if len(_role_list) != 0:
                    _user.role_list = _role_list

        return {'success': True, 'msg': '', 'data': _user_list}


@api.route('/add')
class addUser(Resource):
    @api.parameters(parameters.UserAddParameters())
    @api.response(BaseSchema(many = False))
    @checkToken
    def get(self, args):
        """
        add a new user
        :param args:
        :return:
        """
        log.info("============== start add user ==============")
        _account = args['account']
        _password = args['password']
        _email = args['email']
        _role = eval(args['role'])

        if type(_role) is not list:
            _msg = "this _role %s is not list" % _role
            log.error("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}

        _realname = args['realname']

        _rolestr = ''
        for _id in _role:
            _rolestr = '%s%s|' % (_rolestr, _id)

        from app.modules.common.dbUtil import createId
        _user = User(createId('u'), _account, _realname, "|%s" % _rolestr, GetMD5(_password), '', '', _email)
        db.session.add(_user)
        return DbCommit()


@api.route('/del')
class delUser(Resource):
    @api.parameters(parameters.UserDelParameters())
    @api.response(BaseSchema(many = False))
    @checkToken
    def get(self, args):
        """
        delete a user
        :param args:
        :return:
        """
        log.info("============== start del user ==============")
        _id = args['id']

        if str(_id) == str(BaseConfig.ROLE_ADMIN_ID):
            _msg = 'del user , admin can not del'
            log.error("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}

        _user = User.query.filter_by(id = _id).first()
        if _user is None:
            _msg = 'del user , user %s is not exist' % _id
            log.error("============== del user %s ==============" % _msg)
            return {'success': False, 'msg': _msg}
        else:
            db.session.delete(_user)
            return DbCommit()


@api.route('/update')
class updateUser(Resource):
    @api.parameters(parameters.UserUpdateParameters())
    @api.response(BaseSchema(many = False))
    @checkToken
    def get(self, args):
        """
        update user info
        :param args:
        :return:
        """
        log.info("============== start update user ==============")
        _update_pass = args['update_pass']
        _id = args['id']

        if str(_id) == str(BaseConfig.ROLE_ADMIN_ID):
            _msg = 'update user , admin can not update'
            log.error("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}

        _user = User.query.filter_by(id = _id).first()
        if _user is None:
            _msg = 'update user , user %s is not exist' % _id
            log.error("============== update user %s ==============" % _msg)
            return {'success': False, 'msg': _msg}
        else:
            if bool(_update_pass):
                _old_password = args['old_password']
                _new_password = args['new_password']
                if _old_password is None:
                    _msg = 'update user , user %s password is none' % _id
                    log.error("============== update user %s ==============" % _msg)
                    return {'success': False, 'msg': _msg}
                elif str(GetMD5(_old_password)) != str(_user.password):
                    _msg = 'update user , user %s password is not correct' % _id
                    log.error("============== update user %s ==============" % _msg)
                    return {'success': False, 'msg': _msg}
                else:
                    _user.password = GetMD5(_new_password)
            _user.account = args['account']
            _user.realname = args['realname']
            _user.email = args['email']
            _rolestr = ''
            _role_list = eval(args['role_list'])
            if type(_role_list) is not list:
                _msg = "this _role_list %s is not list" % _role_list
                log.error("============== %s ==============" % _msg)
                return {'success': False, 'msg': _msg}

            for _role_id in _role_list:
                _rolestr = '%s%s|' % (_rolestr, _role_id)
            _user.role = "|%s" % _rolestr
            return DbCommit()


@api.route('/addRoleForUser')
class addRoleForUser(Resource):
    @api.parameters(parameters.AddRoleForUserParameters())
    @api.response(BaseSchema(many = False))
    @checkToken
    def get(self, args):
        """
        为用户添加角色
        :param args:
        :return:
        """
        log.info("============== start add role for user ==============")
        _user_id = args['id']
        _role_name = args['role_name']
        return addRoleForUser(_user_id, _role_name)


def addRoleForUser(_user_id, _role_name):
    _user = User.query.filter_by(id = _user_id).first()
    if _user is None:
        _msg = "用户%s不存在" % _user_id
        log.error("============== %s ==============" % _msg)
        return {'success': False, 'msg': _msg}

    _role = Role.query.filter_by(role_name = _role_name).first()
    if _role is None:
        _msg = '角色名%s不存在' % _role_name
        log.error("============== %s ==============" % _msg)
        return {'success': False, 'msg': _msg}

    if '|%s|' % _role.role_id in _user.role:
        _msg = '用户%s已有角色%s' % (_user_id, _role_name)
        log.error("============== %s ==============" % _msg)
        return {'success': False, 'msg': _msg}
    _user.role = "%s%s|" % (_user.role, _role.role_id)
    return DbCommit()


@api.route('/delRoleForUser')
class delRoleForUser(Resource):
    @api.parameters(parameters.AddRoleForUserParameters())
    @api.response(BaseSchema(many = False))
    @checkToken
    def get(self, args):
        """
        删除用户角色
        :param args:
        :return:
        """
        log.info("============== start del role for user ==============")
        _user_id = args['id']
        _role_name = args['role_name']

        _user = User.query.filter_by(id = _user_id).first()
        if _user is None:
            _msg = "用户%s不存在" % _user_id
            log.error("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}

        _role = Role.query.filter_by(role_name = _role_name).first()
        if _role is None:
            _msg = '角色名%s不存在' % _role_name
            log.error("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}

        if '|%s|' % _role.role_id not in _user.role:
            _msg = '用户%s没有角色%s' % (_user_id, _role_name)
            log.error("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}
        _user.role = str(_user.role).replace('|%s|' % _role.role_id, '|')
        return DbCommit()


@api.route('/resetUserPass')
class resetUserPass(Resource):
    @api.parameters(parameters.ResetUserPassParameters())
    @api.response(BaseSchema(many = False))
    @checkToken
    def post(self, args):
        """
        重置用户密码
        :param args:
        :return:
        """
        log.info("============== start reset user password ==============")
        _account = args['account']
        _token_id = args['token_id']

        _user = User.query.filter_by(account = _account).first()
        if _user is None:
            _msg = "用户%s不存在" % _account
            log.error("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}

        _token = LoginToken.query.filter_by(token_id = _token_id).first()
        _login = User.query.filter_by(id = _token.user_id).first()
        if _login is None:
            _msg = "登录用户%s不存在" % _token.user_id
            log.error("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}
        _role = Role.query.filter_by(role_name = 'admin').first()
        if _token.user_id != _user.id and '|%s|' % _role.role_id not in _login.role:
            _msg = "当前用户没有权限重置密码 user=%s login=%s" % (_user.id, _token.user_id)
            log.error("============== %s ==============" % _msg)
            return {'success': False, 'msg': _msg}

        _user.password = "21218cca77804d2ba1922c33e0151105"
        return DbCommit()
